#include "qtablepages.h"
#include "defines.h"
#include "customdialog.h"
#include "logmanagement.h"
// #include "usermanagement.h"

#include <QHeaderView>
#include <QLayout>
#include <QDebug>
#include <QDateTime>

QTablePages::QTablePages(QWidget *parent) : QWidget(parent),
                                            m_tableView(new ToolTipTableView(this)),
                                            m_pageNavBar(new PageNavigator(this)),
                                            m_dataModel(nullptr),
                                            m_pageLines(20),
                                            m_currentPage(1),
                                            m_totalPages(1)
{

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(m_tableView);
    layout->addWidget(m_pageNavBar);
    layout->setContentsMargins(30, 9, 30, 0);
    layout->setSpacing(6);
    setLayout(layout);

    connect(m_pageNavBar, &PageNavigator::SigCurrentPageChanged, this, &QTablePages::OnPageChanged);
    connect(m_pageNavBar, &PageNavigator::SigPageLinesChanged, [=](const QString &count)
            { setPageLines(count.toInt()); });
    connect(&LogManagement::getInstance(), &LogManagement::databaseReconnected, [=]()
            {
                m_dataModel->updateLoadState(false);
                refreshData(); 
                m_tableView->viewport()->update(); });
    connect(&LogManagement::getInstance(), &LogManagement::databaseDisconnected, [=]()
            {
                m_dataModel->updateLoadState(false);
                refreshData();
                m_dataModel->removeRows(0, m_dataModel->rowCount()); 
                m_tableView->reset();
                m_tableView->clearSelection();
                m_tableView->update(); });
}

QTablePages::~QTablePages()
{
}

void QTablePages::InitTableForm(RemoteTableModel *dataModel, int pageLines)
{
    if (!dataModel)
        return;

    m_dataModel = dataModel;
    m_pageLines = pageLines;
    m_currentPage = 1;

    m_tableView->setModel(m_dataModel);
    connect(m_dataModel, &RemoteTableModel::dataRefreshed, this, [this]()
            {
        m_totalPages = (m_dataModel->totalCount() + m_pageLines - 1) / m_pageLines;
        m_pageNavBar->updateNavbar(m_dataModel->totalCount(), m_pageLines);
        
        // 更新总记录显示
        m_pageNavBar->setLabelTotalRecord(m_dataModel->totalCount()); });
}
void QTablePages::setPageLines(int lines)
{
    if (lines > 0 && m_dataModel)
    {
        m_pageLines = lines;
        m_currentPage = 1; // 重置到第一页
        m_dataModel->setPageSize(lines);
        updateTableView(); // 刷新数据
    }
}

void QTablePages::updatePageNavigator()
{
    if (!m_dataModel)
        return;

    int totalRecords = m_dataModel->totalCount();
    if (totalRecords == 0)
    {
        return;
    }
    m_pageNavBar->updateNavbar(totalRecords, m_pageLines);
    m_totalPages = (totalRecords + m_pageLines - 1) / m_pageLines;
}

void QTablePages::refreshData(const QString &dateFrom, const QString &dateTo, const QString &content)
{
    if (!m_dataModel)
        return;

    QString filter;
    if (!dateFrom.isEmpty() && !dateTo.isEmpty())
    {
        filter = QString("time BETWEEN '%1' AND '%2'").arg(dateFrom).arg(dateTo);
    }

    if (!content.isEmpty())
    {
        if (!filter.isEmpty())
            filter += " AND ";
        filter += QString("content LIKE '%%1%'").arg(content);
    }

    m_filter = filter.isEmpty() ? "1=1" : filter;

    QString query = QString(
                        "SELECT *, COUNT(*) OVER() AS total_count "
                        "FROM %1 "
                        "WHERE %2 "
                        "ORDER BY time DESC "
                        "LIMIT %3 OFFSET %4")
                        .arg(
                            m_dataModel->getTableName(),
                            m_filter.isEmpty() ? "1=1" : m_filter,
                            QString::number(m_pageLines),
                            QString::number((m_currentPage - 1) * m_pageLines));

    m_dataModel->refresh(query);
    updatePageNavigator();
}

void QTablePages::OnPageChanged(int index)
{
    m_currentPage = index;
    updateTableView();
}

void QTablePages::updateTableView()
{
    if (!m_dataModel)
        return;

    int offset = (m_currentPage - 1) * m_pageLines;

    QString query = QString(
                        "SELECT *, COUNT(*) OVER() AS total_count "
                        "FROM %3 "
                        "WHERE %1 "
                        "ORDER BY time DESC "
                        "LIMIT %2 OFFSET %4")
                        .arg(m_filter.isEmpty() ? "1=1" : m_filter)
                        .arg(m_pageLines)
                        .arg(m_dataModel->getTableName())
                        .arg(offset);

    m_dataModel->refresh(query);
}

void QTablePages::onDeleteButtonClicked(const QModelIndex &index)
{
    CustomDialog *dialog = new CustomDialog("确认删除该条日志吗?", this);
    if (dialog->exec() == QDialog::Accepted)
    {
        if (!m_dataModel || !index.isValid())
            return;

        int row = index.row();
        QString id_ = m_dataModel->getID(row);
        std::string sql = "DELETE FROM " + m_dataModel->getTableName().toStdString() +
                          " WHERE id = '" + id_.toStdString() + "';";
        // 执行删除
        if (m_dataModel->removeRow(row, QString::fromStdString(sql)))
        {
            // 删除成功后处理
            int currentRowCount = m_dataModel->rowCount();

            // 如果当前页没有数据且不是第一页
            if (currentRowCount == 0 && m_currentPage > 1)
            {
                m_currentPage--;
            }

            // 重新加载数据
            updateTableView();

            // 更新分页信息
            m_totalPages = (m_dataModel->totalCount() + m_pageLines - 1) / m_pageLines;
            m_pageNavBar->updateNavbar(m_dataModel->totalCount(), m_pageLines);
        }
        else
        {
            QMessageBox::warning(this, "错误", "删除记录失败");
        }
    }
    delete dialog;
}

void QTablePages::exportToCSV(int lastColumnCount)
{
    if (!m_dataModel)
        return;

    QFileDialog dialog(this);
    dialog.setOptions(QFileDialog::DontUseNativeDialog);
    dialog.setWindowTitle(tr("表格导出"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setNameFilter(tr("CSV Files (*.csv)"));
    dialog.setStyleSheet("color: white;");
    dialog.setStyleSheet(
        "QFileDialog {"
        "   background-color: black;"
        "   color: white;"
        "}"
        "QWidget {"
        "   background-color: black;"
        "   color: white;"
        "}"
        "QLabel {"
        "   color: white;"
        "}"
        "QLineEdit {"
        "   background-color: #333;"
        "   color: white;"
        "}"
        "QPushButton {"
        "   background-color: #444;"
        "   color: white;"
        "}"
        "QListView, QTreeView {"
        "   background-color: #222;"
        "   color: white;"
        "}"
        "QHeaderView::section {"
        "   background-color: #333;"
        "   color: white;"
        "}");

    QString saveFileName;
    if (dialog.exec())
    {
        saveFileName = dialog.selectedFiles().first();
        QFileInfo fileInfo(saveFileName);
        if (fileInfo.suffix().toLower() != "csv")
        {
            saveFileName += ".csv";
        }
    }

    if (saveFileName.isEmpty())
        return;

    // 构造不带分页的查询
    QString tableName = m_dataModel->getTableName();
    QString filter = m_filter.isEmpty() ? "1=1" : m_filter;
    QString query = QString("SELECT * FROM %1 WHERE %2 ORDER BY time DESC")
                        .arg(tableName, filter);

    auto client = m_dataModel->getClient();
    client->ExecuteQuery(query.toStdString(), [this, lastColumnCount, saveFileName](const std::vector<Record> &records)
                         {
        // 处理结果写入CSV
        QFile file(saveFileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QMetaObject::invokeMethod(this, [this]() {
                QMessageBox::warning(this, "错误", "无法创建文件");
            }, Qt::QueuedConnection);
            return;
        }

        QTextStream out(&file);
        QStringList headers;
        QStringList columnOrder = m_dataModel->columnOrder();

        // 排除ID和操作列
        int exportColumns = columnOrder.size() - lastColumnCount;
        for (int i = 1; i < exportColumns; ++i) {
            QString header = m_dataModel->columnMapping().value(columnOrder[i]);
            headers << header;
        }
        out << headers.join(",") << "\n";

        for (const auto &dbRecord : records) {
            auto dataIt = dbRecord.find("data");
            if (dataIt == dbRecord.end()) continue;

            const auto &data = dataIt->second;
            QStringList rowValues;

            for (int i = 1; i < exportColumns; ++i) {
                QString columnKey = columnOrder[i];
                auto valueIt = data.find(columnKey.toStdString());
                QString value = (valueIt != data.end()) ? 
                                QString::fromStdString(valueIt->second).replace("\n", " ").replace(",", ";") : 
                                "";
                rowValues << value;
            }
            out << rowValues.join(",") << "\n";
        }

        file.close();

        QMetaObject::invokeMethod(this, [this]() {
            QMessageBox::information(this, "导出完成", "数据已成功导出到CSV文件。");
        }, Qt::QueuedConnection); });
}

RemoteTableModel *QTablePages::getDataModel()
{
    return m_dataModel;
}

QString QTablePages::getFilter()
{
    return m_filter;
}

ToolTipTableView::ToolTipTableView(QWidget *parent)
    : QTableView(parent)
{
    horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    setMouseTracking(true);
}

bool ToolTipTableView::viewportEvent(QEvent *event)
{
    if (event->type() == QEvent::ToolTip)
    {
        QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
        QModelIndex index = indexAt(helpEvent->pos());

        if (index.isValid())
        {
            QRect rect = visualRect(index);
            QVariant data = model()->data(index);
            QString text = data.toString();

            QPalette toolTipPalette;
            toolTipPalette.setColor(QPalette::ToolTipBase, Qt::darkGray);
            toolTipPalette.setColor(QPalette::ToolTipText, Qt::white);
            QToolTip::setPalette(toolTipPalette);

            // 显示工具提示
            QToolTip::showText(helpEvent->globalPos(), text, this, rect);
            return true;
        }

        QToolTip::hideText();
        event->ignore();
        return true;
    }

    return QTableView::viewportEvent(event);
}